/*
	Copyright (C) 2010 Salil Bhagurkar

	This file is part of salil64

	salil64 is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	salil64 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with salil64.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "types.h"
#include "portio.h"

static u8 *vgafb = (u8 *)0xb8000;
static u16 cursor = 0;

static u8 text_color = 7;

static void set_hw_cursor()
{
	outb(0x3d4, 15);
	outb(0x3d5,(u8)cursor);
	outb(0x3d4, 14);
	outb(0x3d5,(u8)(cursor>>8));
}

static u16 get_hw_cursor()
{
	u16 cur;
	outb(0x3d4, 15);
	cur|=inb(0x3d5);
 	outb(0x3d4, 14);
 	cur|=(inb(0x3d5)<<8);
	return cur;
}


static void scroll_screen(void)
{
	int i;
	unsigned int *vidmem=(unsigned int *)vgafb;
	for(i=0;i<80*24;i+=8)	{
		*(vidmem+i)=*(vidmem+i+40);
		*(vidmem+i+1)=*(vidmem+i+1+40);
		*(vidmem+i+2)=*(vidmem+i+2+40);
		*(vidmem+i+3)=*(vidmem+i+3+40);
		*(vidmem+i+4)=*(vidmem+i+4+40);
		*(vidmem+i+5)=*(vidmem+i+5+40);
		*(vidmem+i+6)=*(vidmem+i+6+40);
		*(vidmem+i+7)=*(vidmem+i+7+40);
	}
	cursor -= 80;
}

void print(const char *buf, unsigned len)
{
	unsigned char *vidmem;
	while(len--) {
		if((*buf) == '\n') {
			cursor = cursor/80 * 80 + 80;
		} else if((*buf) == '\b') {
			vidmem = vgafb + cursor * 2;
			*(vidmem-2) = 0;
			cursor--;
		} else {
			vidmem = vgafb + cursor * 2;
			*vidmem = *buf;
			*(vidmem+1) = text_color;
			cursor++;
		}
		buf++;
		if(cursor >= 2000) {
			scroll_screen();
		}
	}
	set_hw_cursor();
}

void clrscr()
{
	int i;
	for(i = 0; i < (80 * 25); i++) {
		vgafb[i * 2] = 0;
		vgafb[i * 2 + 1] = 7;
	}
	cursor = 0;
	set_hw_cursor();
}

